和项目里同一份源码,附带 support.js 与 assets,所以能真的跑起来。
五栏:Home / Log / Scan / Plan / Me。共享餐记录、逐项复核、可选收据分支都在里面。
默认播种两餐(1,520–1,740)。SALMON 那条用来验「编辑载入本餐成分」和「重复保存不加餐」。
三餐 1,990–2,310,超出区间应显示 190–810。
预置一个 3 天前开始的 7 天计划,用来验过去/今天/未来的操作差异、补记、暂停恢复和到期回顾。
商户直连的 Log 订单流存档,整页盖「NOT BUILT」。首页品牌视觉已经放回产品页,不在这里。
下面每一行都是连续操作下的实测值——上一行的状态是下一行的起点。你按同样顺序点应该得到一样的数字。
| 路径 | 应该看到 |
|---|---|
| Scan → 识别 → 进入复核 | 四行:主菜 / 西兰花 / 气泡水 / 一条读不出的饮料。总计 495–600,确认按钮禁用,提示有一行待核对 |
| Resolve 那条饮料 → 选 Black coffee | 总计 495–605,确认按钮解禁 |
| 主菜改 0.75× | 385–475 |
| 接着给主菜加「油」 | 475–565(+90) |
| 接着排除主菜 | 55–85 — 油随菜一起消失,没有残留在总数里 |
| 再把其余全部排除 | 总计 0–0,确认按钮禁用,提示至少留一项 |
| 复核页 → Add a receipt to cross-check | 收据预览;可导入截图 / 重拍 / 暂不添加返回照片草稿 / 编辑遮挡 |
| 编辑遮挡,不加任何遮挡 | 「用这张辅助核对」禁用,提示至少遮挡一处 |
| 遮挡一处 → 用这张辅助核对 | 只读遮挡后的副本;处理中页面写明「餐食仍未计入」 |
| 联合核对 | 主菜/西兰花「照片和收据都有」;气泡水冲突(收据 2、照片 1);Black coffee「只在照片里」;Oat cookie「只在收据上」。后两类默认待核对,不默认吃了,确认按钮禁用 |
| 冲突选「保留照片的 1」;cookie 选「没吃」 | 解禁;cookie 不计入 |
| 连点两次「确认这一餐」 | Log 只多一条,495–605;Home 合计同步 |
| 处理中点「Simulate an unreadable receipt」 | 失败页;可重试或放弃收据,照片阶段的选择全部保留 |
| 开始识别后立刻切到 Home,等 3 秒再回 Scan | 停在采集选择页,晚到的结果不会把你拽回复核页 |
| In range → 编辑 SALMON → 连点三次保存 | 仍 2 餐,餐名不变,落点是 Log(不是 Scan 成功页) |
| 接着再走一次完整采集并确认 | 这次应该多一餐,共 3 餐 |
| Over range 场景 | 合计 1,990–2,310,超出 190–810 |
| 联合核对后点「Drop the receipt」 | 回到添加收据之前的照片草稿:cookie 消失、水恢复、总计与之前一致 |
| 只解决水的冲突,不动 cookie | 确认仍然禁用 —— cookie 标「Waiting for your call」,不算已排除 |
| 冲突选「I had 1 of them」 | Bought 2 不变,旁边多一行 You had 1;两者分开计算 |
| 切到 Barcode 模式,或从 Log 编辑旧餐 | 不出现收据入口 |
| 编辑旧餐时看顶部 | 写「This meal is already counted — your changes are not saved yet」,不再是 Nothing counts yet |
| 键盘:Tab 到任意 chip 按 Enter/空格 | 与点击等效;禁用项不响应 |
| Plan 组 | |
| 复核页:所有行都已解决,但份量一个没碰 | 确认仍禁用,提示「默认 1× 不算你的答复」;逐项点一次份量后才解禁 |
目标编辑器:体重填 68.5 | 接受(允许一位小数) |
体重填 501 | 显示「Weight must be between 25 and 500 kg」,Save 置灰 |
| 下限一路加到等于上限 | 允许相等,不再强制 100 kcal 间隔 |
| Plan → Start a plan → 选天数 → See every day | 逐日预览,每天一条含标题/详情/理由;确认前不创建任何东西 |
| 「进行中的计划」变体 → 看各天按钮 | 过去只有 Mark done(补记);今天三个都有;未来只有 Skip / Replace |
| 补记一个过去的日子 | 标「Done · backfilled today」,写明补记的是哪一天 |
| 暂停 → Resume | 先出日期调整预览:已完成/跳过的不动,只有待做的移动;从明天起算且不与占用日期撞车 |
| End this plan | 只读回顾,计数齐全,无任何操作按钮;写明「没记录不等于失败」 |
新建计划:天数框填 45 / 开始日填 2026-13-45 | 各自报错,「See every day」置灰;填 11 + 2026-08-20 可继续,预览 11 天 |
目标编辑器体重填 68.55 | 接受(不再限制小数位);501 报范围错;abc 报「Numbers only」 |
| Me 组 | |
| Fridge:不选任何份量 | 「I ate this」禁用 |
| 选 0.5 cup 酸奶 → 预览 → 确认吃了 | 预览写明约 51–59 kcal;确认后库存 3 → 2.5 cups,Home 从 440–520 变 491–579,Log 多一条 |
| Add food 加一样 → 再 Remove 掉 | 库存增减,Home 数字全程不变——加和删都不算吃 |
| 选超过库存的量 | 拦下并说明「没有记录、也没有从货架扣掉」 |
| 手动运动:Run / 40 min / Hard | 先给估算 449–607 kcal(标明「未保存」),保存后进历史;Home 的进食数字不变 |
| Health 默认状态 | Not connected,且写明网页上不会弹真实系统授权 |
| 画布外 HEALTH SCENARIOS 八个开关 | 未连接/已连接/部分授权(未授权项显示 Not shared 而不是 0)/今日无数据(四项都显示 No entries today)/数据过时/已撤销/不可用/刷新失败 |
| Data wallet:导出 | 准备中 → 文件 + 时间 + 下载/分享;画布外可切「Export fails」看失败态 |
| 删除产品数据 | 两步确认,任一步可取消;结果页写明「不等于注销登录,你仍处于登录状态」 |
| Sign out | 清理演示会话,并写明已确认的餐食仍然保留 |
| 画布外「DEMO DATE」日期控制 | |
| 进行中的计划 → 画布外 +1 day 点四次(越过 15 日截止) | 自动变 PLAN REVIEW · READ ONLY · REACHED ITS END DATE,七天的操作按钮全部消失,不能再补记 |
| 先清空 Fridge、目标改 2200–2450,再新建计划 | 逐日文案用创建时快照:写「Fridge 当时是空的,自己挑食材」「无法据此指定具体食材」,理由里出现 2,200–2,450;有库存时点名实际物品(Greek yogurt / Rye bread) |
| 对未来某天点 Replace | 换成具体可执行的替代行动(含详情与理由),不是占位文字 |
| 暂停后 Resume 预览 | 「保持原日」里同时列出已完成/已跳过和暂停日之前仍待做的项;待做项从明天连续排,第一个就落在重启日 |
| 第六批修正 | |
开始日填 2026-02-30 / 2026-04-31 | 报「That date does not exist」并置灰(原来被 JS 归一化后照样能建) |
| 开始日填过去日期 | 报「A new plan cannot start before today」 |
| 建计划时选 America/New_York → 暂停 → Resume | 恢复文案显示 America/New_York,不再回落上海 |
| 恢复后同一天有两条行动 | 「有记录天数」按餐食日期去重,不按行动行数 |
| Data wallet 两步删除完成后 | 餐食/库存/计划/运动真的清空,Home/Log/Plan/Me 同步空态;登录保留 |
| 导出 → Download / Share | 下载真实 JSON(仅本演示数据),Share 走系统分享、不可用时回退下载;时间是本次导出时间 |
| 部分授权 → Refresh | 不再变成全授权,未共享项仍是 Not shared;无数据状态刷新后仍是 No entries today |
Add food 填 2abc / Infinity / 0 | 各自报错且无法添加;目录外的食物不再凭空得到 90 kcal,标为能量未知且吃不进记录 |
| 运动历史 → Edit this session;重复点保存 | 可编辑;重复保存不再抛错也不重复新增 |
| 留着 ¾ 草稿和收据快照 → Sign out → Sign back in | 草稿全清、回到采集选择页;已确认的餐食仍在 |
| Fridge 记的餐 → Log 里点 Edit | 不再进空白复核页,改为详情页说明「这餐来自 Fridge,没有逐项复核可重开」并留返回入口 |
| 第七批修正 | |
| 复核里只保留气泡水 | 营养全部 0g,不再凭空得到 22g 蛋白;营养由保留项 × 份量 × 数量算出 |
| 主菜改半份 / 输入 200 g(基准 400 g) | kcal 与营养同步减半;首页、弹层、日报、详情读同一份计算 |
| 画布外 DEMO DATE 调到 8/13 | 首页 0–0 且营养空态;调到 8/11 显示当天两条历史餐的合计 |
| Log 「See earlier records (2)」 | 展开出真实的历史日期分组,每条可点进详情;删除后不会再冒出固定旧记录 |
| 计划 9–15 日,8/11 与 8/12 各有餐 | 「有记录天数」= 2,按餐食日期落在起止区间去重,不看当天有没有排行动 |
| 保存失败 → 恢复 Normal → 点「Retry the same save」 | 重试本身就完成保存,不用再按确认;期间确认按钮禁用并显示保存中 |
| 版本冲突 → 「Re-check against the saved version」 | 同时列出已存版本与你的草稿两个区间,二选一,草稿不丢 |
| 删除产品数据(目标编辑器开着、有下一餐打算、有运动草稿) | 草稿全清(goalDraft/planIntent/exDraft),已存列表清空,登录保留;采集代次 +1 让迟到操作失效 |
| Share | 分享同一个 JSON 文件;平台不支持则说明并指向 Download;取消就是取消,不会自动改成下载 |
| 复核页「Replace with another catalogue item」/「+ 目录餐」 | 可替换/新增真实目录条目(含 kcal 区间),总计随之变化 |
| 画布外 Unfinished draft / Photo no longer available / Saved but refresh failed | 草稿可恢复或重来;照片失效可重选;已保存但刷新失败明说「已保存,不要再存一次」 |
| Sign out → 模拟登录错误 → 重试 → 登录 | 加载态、错误态、重试入口齐全,已存餐食不受影响 |
| 第八批修正 | |
| 输入 200 g(基准 400 g)/替换成 Lentil soup | 营养随之重算:蛋白 25→14(克数)→17(替换成扁豆),不再沿用原菜营养 |
| Log 编辑旧餐改 0.5× 保存 | 营养同步减半(24→12g 蛋白 …),首页摘要跟着变;不再保留旧值也不会变成 Not provided |
| 离线时对计划做 完成/跳过/替换/结束 | 四个都被拦下并说明「没有改动」;恢复 Normal 后同样操作通过 |
| 重试进行中执行 删除产品数据 / 登出 | 挂起的回调作废,不会把已删数据写回;连点三次重试也只产生一条 |
| 结果未知状态点「Discard the draft」 | 回到采集选择页,之后也不会有迟到写入 |
| 第九批修正 | |
| 输入 200 g 后再点 1× / 0.5× | 克数与份量是同一数量的两种输入,一律从基准重算:1× 回到 495–600,0.5× 是基准的一半,不叠乘 |
| 克数填了但没点 Use,或填了非法值 | 确认被拦下并说明「不会被悄悄忽略」 |
| 只留气泡水 + 一杯燕麦拿铁 | 纤维/铁显示 Not provided(拿铁没公布),不会被水的已知 0 盖掉 |
| Fridge 吃 2 片黑麦面包 | 营养按该食物的单位营养 × 数量算(蛋白 6g、碳水 30g),不再是所有食物同一组数 |
| 油 / 酱 | 带自己的营养(油 10g 脂肪、酱 1/4/4),不只是加热量 |
| 离线时 Fridge 添加/吃了/移除 | 三个入口都被拦下,库存和当天记录不变,选择保留 |
| 离线时保存运动 | 失败提示就在运动表单里,输入保留 |
| 保存失败后把主菜改半份,再点「Retry the same save」 | 存下的是原始那次请求(495–605),不是改过的草稿 |
| 重试前先取消编辑、再打开 SALMON | SALMON 保持 1,080–1,220;只取消不切换也不会新增一餐——待保存绑定了会话与目标餐,离开即作废 |
| 照片保存未知(预留 meal-4)→ 从 Fridge 吃一片面包 → 回来重试 | 面包拿到 meal-5,照片重试落在 meal-4,ID 不再撞车 |
| 结束计划失败 → 恢复 → 结束旧计划 → 新建 11 天 | 旧错误条已消失,不会把新计划结束(待处理操作绑定了 plan.id 与会话) |
| 运动保存失败 → 放弃 → 另填 Run 40 → 保存 | 只存下 Run 40;旧的 Walk 待处理操作在放弃时就作废 |
| Plan 失败时切到 Me | Me 的运动区不会出现 Plan 的错误条(每个错误只在自己的界面) |
| 待处理操作的目标已不存在时点重试 | 不执行,改为说明「这条待处理的修改所指的对象已不存在,什么都没有改动」 |
| 运动预览页 | 新增「放弃这次记录」;「Edit」保留已填内容(之前会重置回 Walk 30) |
| 版本冲突下点重试 | 不再空转:冲突只给「重读现状」,重读后才出现「仍然应用我的修改」,也可「放弃我的修改」;离线/结果未知仍是直接重试 |
| 单独触发 Fridge 失败 | 三种模式的说明都能显示(之前挂在 planBlocked 上,Fridge 路径不设它,于是一句都不出) |
| Plan/Fridge/运动失败后 | 三种模式各自文案(离线=没发出去/结果未知=不能断言未写入/版本冲突=别处改过),并提供「重试这次操作」;恢复后重试只执行一次 |
| Fridge 添加失败 → 返回 | 回到表单且 Banana / 2 仍在,不再被清空 |
| 输入 200 g 后 | 份量档不再同时显示选中;切回 1× 时 note 与克数输入一起清除 |
| 保存失败时的餐 ID | 第一次尝试就预留(如 meal-5),重试写入的就是这一条;连点三次重试仍只有一条、ID 唯一;重试途中删除数据不留下悬空预留 |
| 画布外「Saved but refresh failed」→ 正常确认一餐 | 餐真的写进了 Log,横幅说明已保存并给「再读一次结果 / 打开 Log」 |
| Plan 逐日行动 | 点名具体目录餐及区间(如 Cook Chicken and rice bowl 520–600 kcal),Replace 也用同一目录。理由按「一顿主餐的份额」比对,不再拿单餐去比全天区间:1,500–1,800 的目标写「约 600 kcal」,2,200–2,450 写「约 817 kcal」 |
| 320 / 390 / 480 宽度 | 手机稿保持 390pt 真实尺寸:390/480 不溢出;320 下页面横向滚动(有意为之)。三个宽度下最小点击区都仍是 48px。 上一版我用整体缩放消除 320 的溢出,代价是所有控件渲染成 ~25px —— 那是更糟的取舍,已撤回。 |
| prefers-reduced-motion | 扫描动画等全部停止 |
| 打开 Log 行详情再返回 | 焦点进入浮层,关闭后回到打开它的那一行 |
| 画布外 DATA & SAVE 开关 | No records yet/Refresh failed/Offline/Save fails/Version conflict 五种;营养缺失显示 Not provided 而不是 0,并标出「N of M meals did not publish this」+ 来源与更新时间 |
按流程顺序。手机壳是 390×844,长页面在壳内滚动,所以截图只到可视区。



































